module Mat

    abstract Material
    abstract Material1D <: Material
    abstract Material2D <: Material
    abstract Material3D <: Material

    export Material,
            GeneralMaterial,
            Material1D,Material2D,Material3D,Elastic1D,
            setStrain,getStressTangent,updateHistoryPara

    type GeneralMaterial <: Material

        tag::Int64
        rho::Float64
        E0::Float64
        v::Float64
        G0::Float64

        GeneralMaterial(tag::Int64) = new(tag,0.0,0.0,0.3,0.0)
        GeneralMaterial(tag::Int64,E0::Float64) = new(tag,0.0,E0,0.3,E0/2.6)
        GeneralMaterial(tag::Int64,rho::Float64,E0::Float64) = new(tag,rho,E0,0.3,E0/2.6)
        GeneralMaterial(tag::Int64,rho::Float64,E0::Float64,v::Float64) = new(tag,rho,E0,v,E0/2.0/(1.0+v))

    end

    type Elastic1D <: Material1D

        tag::Int64
        rho::Float64
        E0::Float64
        stress::Float64
        strain::Float64
        tangent::Float64

        Elastic1D(tag::Int64,rho::Float64,E0::Float64) = new(tag,rho,E0,0.0,0.0,E0)
        Elastic1D(tag::Int64,E0::Float64) = new(tag,0.0,E0,0.0,0.0,E0)
        Elastic1D(gmat::GeneralMaterial) = new(gmat.tag,gmat.rho,gmat.E0,0.0,0.0,gmat.E0)

    end

    function setStrain(mat::Elastic1D,strain::Float64)
        mat.strain = strain
        nothing
    end

    function getStressTangent(mat::Elastic1D)
        mat.stress = mat.strain*mat.tangent
        nothing
    end

    function updateHistoryPara(mat::Elastic1D)
        nothing
    end

end
